package com.mx.zb.mng.utils;

import java.util.UUID;

public class UnionCode {

	// 64进制字符表 注意用-替换了/，因为如果用于URL的话，正则替换就不方便了
	final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
			'9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
			'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
			'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
			'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
			'Z', '+', '-' };
	
	
	/**
	 * 随机获取UUID字符串(无中划线)	32位
	 * 
	 * @return UUID字符串
	 */
	public static String getUUID() {
		String uuid = UUID.randomUUID().toString();
		return uuid.substring(0, 8) + uuid.substring(9, 13)
		+ uuid.substring(14, 18) + uuid.substring(19, 23)
		+ uuid.substring(24);
	}
	
      
      
    /** 
     * 以64进制（字母加数字）生成UUID，22位（有20或21位的时候前面补0）
     *  
     * @return 
     */  
    public static String getShortUuid() {  
        UUID uuid = UUID.randomUUID();  
        StringBuilder sb = new StringBuilder();  
        sb.append(toString(uuid.getMostSignificantBits()));        
        sb.append(toString(uuid.getLeastSignificantBits()));  
        return sb.toString();  
    }
    
    /**
	 * 把10进制的数字转换成16, 32, 64进制
	 * 
	 * @param number
	 * @param hex  16进制为4， 32为5， 64为6
	 * @param isAddZero 是否在前面补零
	 * @return 
	 */
	public static String toString(long number, int hex, boolean isAddZero) {
		int len= (int)Math.ceil(64.0 / hex); 
		char[] buf = new char[len];
		int charPos = len;
		int radix = 1 << hex;
		long mask = radix - 1;
		do {
			buf[--charPos] = digits[(int) (number & mask)];
			number >>>= hex;
//			System.out.println("pos:"+charPos+" char:"+buf[charPos]);
		} while (isAddZero?charPos != 0:number!=0);		
		return new String(buf, charPos, (len - charPos));
	}
    

	/**
	 * 把10进制的数字转换成64进制
	 * 
	 * @param number
	 * @param shift
	 * @return
	 */
	public static String toString(long number) {		
		return toString(number, 6, true);
	}
	
	/**
	 * 把10进制的数字转换成16进制
	 * 
	 * @param number
	 * @param shift
	 * @return
	 */
	public static String toString16(long number) {
		return toString(number, 4, true);
	}
	
	/**
	 * 把10进制的数字转换成64进制，前面不补0，即可能小于11位
	 * 
	 * @param number
	 * @param shift
	 * @return
	 */
	public static String toStringShort(long number) {
		return toString(number, 6, false);
	}
	
	/**
	 * 把10进制的数字转换成32进制，前面不补0，即可能小于13位
	 * 
	 * @param number
	 * @param shift
	 * @return
	 */
	public static String toString32Short(long number) {
		return toString(number, 5, false);
	}
	
	/**
	 * 把10进制的数字转换成64进制，前面不补0，即可能小于16位
	 * 
	 * @param number
	 * @param shift
	 * @return
	 */
	public static String toString16Short(long number) {
		return toString(number, 4, false);
	}

	
	/**
	 * 把16,32,64进制的字符串转换成10进制
	 * 
	 * @param decompStr
	 * @param hex 16进制为4，32为5，64为6
	 * @return
	 */
	public static long toLong(String decompStr,int hex) {
		long result = 0;
		for (int i = decompStr.length() - 1; i >= 0; i--) {
			if (i == decompStr.length() - 1) {
				result += getCharIndexNum(decompStr.charAt(i));
				continue;
			}
			for (int j = 0; j < digits.length; j++) {
				if (decompStr.charAt(i) == digits[j]) {
					result += ((long) j) << hex * (decompStr.length() - 1 - i);
				}
			}
		}
		return result;
	}
	
	/**
	 * 把64进制的字符串转换成10进制
	 * 
	 * @param decompStr
	 * @return
	 */
	public static long toLong(String decompStr) {
		
		return toLong(decompStr, 6);
	}
	
	/**
	 * 把64进制的字符串转换成10进制
	 * 
	 * @param decompStr
	 * @return
	 */
	public static long toLong16(String decompStr) {
		
		return toLong(decompStr, 4);
	}
	
	/**
	 * 把64进制的字符串转换成10进制
	 * 
	 * @param decompStr
	 * @return
	 */
	public static long toLong32(String decompStr) {
		
		return toLong(decompStr, 5);
	}
	
	

	private static long getCharIndexNum(char ch) {
		int num = ((int) ch);
		if (num >= 48 && num <= 57) {
			return num - 48;
		} else if (num >= 97 && num <= 122) {
			return num - 87;
		} else if (num >= 65 && num <= 90) {
			return num - 29;
		} else if (num == 43) {
			return 62;
		} else if (num == 45) {
			return 63;
		}
		return 0;
	}
	
	public static void main(String[] args) {
		for(int i=0;i<100;i++){
//			long t=System.currentTimeMillis();
//			String s=toString32Short(t);
//			long e=toLong32(s);
//			System.out.println(t);
//			System.out.println(s);
//			System.out.println(e);
//			System.out.println("=======================");
		}
		System.out.println(1 << 26);
		System.out.println(toString32Short(70947777));
		System.out.println(toLong32("vvvvvv"));
		for(int i=0;i<5;i++){
			System.out.println(getUUID());
		}		
		
		System.out.println(getShortUuid());
		
//		System.out.println();
	}
}
